package cource.FinalExam;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * 将配置编码设置为gbk,或者会出现乱码
 * 思路
 * 1.设置一个frame
 * 2.设置一个选择滚动，Choice组件指定一些文件路径，文本输入框TextFiled用于选择输入文件路径
 * 3.设置一个查询按钮，同时注册一个监视器，给出行为为文件读取和查找
 * 4.在线程里面设置时间
 * 5.设置两个文本域，用于显示查找结果和时间
 * 6.将组件组合
 *
 * @author zeng
 * @data 2021/05/16 11:54
 */

//二分查找线程

public class SeekThree {
    //为了使代码看起来简洁，将组件设置在类里面
    //设置frame窗口
    Frame frame = new Frame("Seek");
    //设置两个个dialog对话框，两个按钮，一个查询成功，一个查询失败
    Dialog d1 = new Dialog(frame, "Success",false);
    Dialog d2 = new Dialog(frame, "Error",false);
    Button success = new Button("查询成功");
    Button failure = new Button("查询失败");
    //设计一个面板容器
    Panel p = new Panel();
    //设置查找内容输入选择框和导入按钮已经查询数字,添加图片,设置FileDialog对象，用于打开文件
//    Choice ChoicePath = new Choice();
    FileDialog fd = new FileDialog(frame, "选择要打开的文件", FileDialog.LOAD);
    Button SeekFile = new Button("查询文件");
    TextField Filename = new TextField(20);
    Button Input = new Button("导入");
    JLabel key = new JLabel("查询内容:");
    TextField SeekKey = new TextField(4);
    ImageIcon img = new ImageIcon("D:\\Googl浏览器下载\\img\\logo3.jpg");
    JLabel ImaLabel = new JLabel(img);
    //创建一个查询按钮
    Button seek = new Button("查询");
    //设计两个标签，表示顺序查找和二分查找
    Label OrderSeekLabel = new Label("顺序查找:");
    Label BinarySeekLabel = new Label("二分查找:");
    //设计四个文本域，用来显示顺序查找和二分查找的查询结果、时间
    TextField OrderTime = new TextField(10);
    TextField BinaryTime = new TextField(10);
    TextField OrderResult = new TextField(10);
    TextField BinaryResult = new TextField(10);
    TextField OrderCount = new TextField();
    TextField BinaryCount = new TextField();
    //设置一个三个Box(一个水平Box, 两个个垂直Box),对应的查找分布用一个垂直Box装起来，再用一个水平Box将两个垂直Box装起来
    Box Hbox = Box.createHorizontalBox();
    Box VboxOrder = Box.createVerticalBox();
    Box VboxBinary = Box.createVerticalBox();

    /**
     * @param Vbox    , 指垂直容器
     * @param Seek    ， 标签
     * @param Time    ， 查找时间
     * @param Result， 查找结果，true或false
     */
    public void AssemblyComponent(Box Vbox, Label Seek, TextField Time, TextField Result, TextField Counts) {

        //添加查询次数
        JLabel SeekCounts = new JLabel("次数:");
        //创建时间和结果标签
        JLabel timeLable = new JLabel("时间:");
        JLabel resultLael = new JLabel("结果:");
        //设置三个水平Box,组装标签和文本域
        Box h1 = Box.createHorizontalBox();
        Box h2 = Box.createHorizontalBox();
        Box h3 = Box.createHorizontalBox();
        h1.add(timeLable);
        h1.add(Time);
        h2.add(resultLael);
        h2.add(Result);
        h3.add(SeekCounts);
        h3.add(Counts);
        //从上到下一次为标签，时间，结果
        Vbox.add(Seek);
        //设置垂直间隔
        Vbox.add(Box.createVerticalStrut(1));
        Vbox.add(h1);
        Vbox.add(Box.createVerticalStrut(1));
        Vbox.add(h2);
        Vbox.add(Box.createVerticalStrut(1));
        Vbox.add(h3);
    }

    //初始函数
    public void init() {
        //设置SeekFile按钮监视器
        SeekFile.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                fd.setVisible(true);
                String dir = fd.getDirectory();
                String filename = fd.getFile();
                Filename.setText(dir + filename);

            }
        });
        //将查询成功按钮组装到Dialog中,并设置大小，位置,设置事件
        success.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                d1.setVisible(false);
            }
        });
        failure.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                d2.setVisible(false);
            }
        });
        //从上到下开始组装界面，界面可以分为两个部分，上面是Panle容器，下面为Box容器

        //组装Panle,给ChoicePath增加文件路径,Panle默认布局格式为FlowLayout，不需重复设置
//        ChoicePath.add("D:\\Googl浏览器下载\\tinyAllowlist.txt");
//        ChoicePath.add("D:\\Googl浏览器下载\\tinyText.txt");
//        ChoicePath.add("D:\\Googl浏览器下载\\largeAllowlist.txt");
//        ChoicePath.add("D:\\Googl浏览器下载\\largeTest.txt");
//        ChoicePath.add("D:\\Googl浏览器下载\\largeText.txt");
        d1.add(success);
        d2.add(failure);
        d1.pack();
        d1.setLocationRelativeTo(null);
        d2.pack();
        d2.setLocationRelativeTo(null);
        //给Input组件添加行为
        InputListener inputListener = new InputListener(Filename);
        Input.addActionListener(inputListener);
        //给seek组件添加监视器
        seek.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent act) {
                //获得路径和带查找数字
                String filePath = inputListener.filePath;
                String keystr = SeekKey.getText();
                File f = new File(filePath);
                //创建顺序查找和二分查找线程
                if (!f.isFile() || keystr.equals("") || !filePath.endsWith("txt")) {
                    d2.setVisible(true);
                } else {
                    //写入文件数据并设置数组
                    BufferedReader bf = null;
                    //设置集合接收数据
                    List list = new ArrayList();
                    Integer[] arr = null;
                    try {
                        bf = new BufferedReader(new FileReader(new File(filePath)));
                        //接收读取的字符
                        String str = null;
                        while((str = bf.readLine()) != null){
                            list.add(Integer.parseInt(str.replaceAll("\\s*", "")));//转化为数字
                        }
                        //转换为数组并排序
                        arr = new Integer[list.size()];
                        list.toArray(arr);
                        Arrays.sort(arr);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        //关闭文件资源
                        if(bf != null){
                            try {
                                bf.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    int key = Integer.parseInt(keystr);
                    OrderSeekThread orderSeekThread = new OrderSeekThread(arr, key);
                    BinarySeekThread binarySeekThread = new BinarySeekThread(arr, key);
                    orderSeekThread.start();
                    binarySeekThread.start();
                    while (true) {
                        //当线程运行结束
                        if (orderSeekThread.getState() == Thread.State.TERMINATED && binarySeekThread.getState() == Thread.State.TERMINATED) {
//                            OrderTime.setText(orderSeekThread.starttime + "-" + orderSeekThread.endtime);
                            if(orderSeekThread.flag == "true"){
                                d1.setVisible(true);
                            }else {
                                d2.setVisible(true);
                            }
                            OrderTime.setText(orderSeekThread.gaptime);
                            OrderResult.setText(orderSeekThread.flag);
                            OrderCount.setText(orderSeekThread.Count + "");
//                            BinaryTime.setText(binarySeekThread.starttime + "-" + binarySeekThread.endtime);
                            BinaryTime.setText(binarySeekThread.gaptime);
                            BinaryResult.setText(binarySeekThread.flag);
                            BinaryCount.setText(binarySeekThread.Count + "");
                            break;
                        }
                    }
                }
            }
        });
        p.add(SeekFile);
        p.add(Filename);
        p.add(Input);
        p.add(key);
        p.add(SeekKey);
        p.add(seek);
        p.add(ImaLabel);

        //组装下面的组件
        AssemblyComponent(VboxOrder, OrderSeekLabel, OrderTime, OrderResult, OrderCount);
        AssemblyComponent(VboxBinary, BinarySeekLabel, BinaryTime, BinaryResult, BinaryCount);
        Hbox.add(VboxOrder);
        Hbox.add(VboxBinary);
        //整体组装，将p和Hbox组装到Frame中，设置Frame布局为BorderLayout,但是Frame默认布局为BorderLayout,所以不需要设置
        frame.add(p, BorderLayout.NORTH);
        frame.add(Hbox);

        //设置大小，位置，可见
        frame.pack();//自动比配大小
        frame.setLocationRelativeTo(null);//设置为居中
        frame.setVisible(true);
        //设置视图,对话框可以关闭即点击✗有相应行为
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        d1.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                d1.setVisible(false);
            }
        });
        d2.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                d2.setVisible(false);
            }
        });
    }

    public static void main(String[] args) {
        new SeekThree().init();
    }
}
